package com.yokead.controller.sysadmin.domain;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.jiangzeyin.StringUtil;
import cn.jiangzeyin.common.JsonMessage;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yokead.common.Config;
import com.yokead.common.base.AdminBaseControl;
import com.yokead.common.tools.UrlPath;
import com.yokead.controller.domain.KhDoMainControl;
import com.yokead.service.domain.DoMainServer;
import com.yokead.system.init.InitUserName;
import com.yokead.system.log.LogType;
import com.yokead.system.log.SystemLog;
import com.yokead.util.EncryptUtil;
import com.yokead.util.JsonUtil;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.stream.Collectors;

/**
 * @author jiangzeyin
 * @date 2017/10/11
 */
@Controller
@RequestMapping("sysadmin")
public class KhDoMainConfControl extends AdminBaseControl {
    @Resource
    private DoMainServer doMainServer;

    static final String KEY = "customer_diy";

    @RequestMapping(value = "adkh.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public String adkh() {
        return "sysadmin/domain/adkh";
    }

    @RequestMapping(value = "del_kh_domain.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public String del_kh_domain(String url, String name) {
        if (StringUtil.isEmpty(url)) {
            return JsonMessage.getString(400, "请输入链接");
        }
        synchronized (KhDoMainControl.class) {
            JSONObject jsonObject;
            try {
                jsonObject = doMainServer.getUrls();
            } catch (IOException e) {
                SystemLog.LOG(LogType.CONTROL_ERROR).error("读取异常", e);
                return JsonMessage.getString(500, "删除客户链接时，系统异常，请稍后重试");
            }
            if (jsonObject == null) {
                return JsonMessage.getString(500, "删除客户链接时，系统异常，请稍后重试：-3");
            }
            JSONObject customer = jsonObject.getJSONObject(KEY);
            if (customer == null) {
                return JsonMessage.getString(400, "删除客户链接时，系统异常，请稍后重试：-4");
            }
            JSONArray jsonArray = customer.getJSONArray(name);
            if (jsonArray == null) {
                return JsonMessage.getString(400, "没有对应人员信息");
            }
            if (!jsonArray.contains(url)) {
                return JsonMessage.getString(400, "没有此域名记录");
            }
            JsonMessage tip = removeConfig(url);
            if (tip != null) {
                return tip.toString();
            }
            jsonArray.remove(url);
            String path = Config.DnsPodConfig.getDnsPodDomainListFile();
            // getBootPath() + "/domain_list.conf";
            try {
                JsonUtil.saveJson(path, jsonObject);
            } catch (IOException e) {
                SystemLog.LOG(LogType.CONTROL_ERROR).error("删除异常", e);
                return JsonMessage.getString(500, "删除异常");
            }
            return JsonMessage.getString(200, "ok");
        }
    }

    public JsonMessage removeConfig(String url) {
        // 删除文件
        try {
            SystemLog.LOG().info(InitUserName.getUserName() + "  删除" + url);
            JSONArray doMain = UrlPath.start(Config.Nginx.getNginxConfigPath(), UrlPath.Type.DoMain);
            for (Object aDoMain : doMain) {
                JSONObject jsonObject1 = (JSONObject) aDoMain;
                String url_ = jsonObject1.getString("url");
                if (url.equals(url_)) {
                    String confPath = jsonObject1.getString("confPath");
                    try {
                        String path = EncryptUtil.decrypt(confPath);
                        File file = new File(path);
                        File newFile = new File(file.getParentFile(), file.getName() + "_back");
                        if (newFile.exists()) {
                            return new JsonMessage(400, "改域名记录信息不正确");
                        }
                        if (!file.renameTo(newFile)) {
                            return new JsonMessage(400, "域名信息记录失败");
                        }
                    } catch (Exception e) {
                        SystemLog.ERROR().error("解密异常", e);
                        return new JsonMessage(400, "系统删除中异常");
                    }
                    break;
                }
            }
        } catch (IOException e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("获取域名异常", e);
            return new JsonMessage(500, "处理异常:-1");
        }
        return null;
    }

    @RequestMapping(value = "save_kh_domain.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public String save_kh_domain(String url, String name) {
        if (StringUtil.isEmpty(url)) {
            return JsonMessage.getString(400, "请输入链接");
        }
        if (StringUtil.isEmpty(name) || StringUtil.isChinese(name)) {
            return JsonMessage.getString(400, "请选择人员");
        }
        synchronized (KhDoMainControl.class) {
            JSONObject jsonObject;
            try {
                jsonObject = doMainServer.getUrls();
            } catch (IOException e) {
                SystemLog.LOG(LogType.CONTROL_ERROR).error("读取异常", e);
                return JsonMessage.getString(500, "保存系统异常，请稍后重试");
            }
            if (jsonObject == null) {
                return JsonMessage.getString(500, "系统异常，请稍后重试：-1");
            }
            JSONObject customer = jsonObject.getJSONObject(KEY);
            if (customer == null) {
                customer = new JSONObject();
                jsonObject.put(KEY, customer);
            }
            //return JsonMessage.getString(400, "系统异常，请稍后重试：-2");
            JSONArray jsonArray = customer.getJSONArray(name);
            if (jsonArray == null) {
                jsonArray = new JSONArray();
                customer.put(name, jsonArray);
            }
            if (jsonArray.contains(url)) {
                return JsonMessage.getString(401, "域名已经存在");
            }
            jsonArray.add(url);
            String path = Config.DnsPodConfig.getDnsPodDomainListFile();// getBootPath() + "/domain_list.conf";
            try {
                JsonUtil.saveJson(path, jsonObject);
            } catch (IOException e) {
                SystemLog.LOG(LogType.CONTROL_ERROR).error("保存异常", e);
                return JsonMessage.getString(500, "保存异常");
            }
            return JsonMessage.getString(200, "ok");
        }
    }

    /**
     * 检查域名是否绑定本地设置的ip
     *
     * @return list
     */
    @RequestMapping(value = "check_domain.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public String checkCustomerDomain(String domains) {
        JSONArray domainList;
        try {
            domainList = JSONArray.parseArray(domains);
            if (CollUtil.isEmpty(domainList)) {
                return JsonMessage.getString(500, "请传入需要检查的域名");
            }
        } catch (Exception e) {
            SystemLog.ERROR().error("解析域名列表失败", e);
            return JsonMessage.getString(500, "错误的域名列表");
        }
        String defaultIp = Config.Admin.getDefaultIp();
        if (StrUtil.isEmpty(defaultIp)) {
            return JsonMessage.getString(500, "后台未配置default_ip 无法检测");
        }
        JSONArray array = checkDomainIp(domainList, defaultIp);
        return JsonMessage.getString(200, "", array);
    }

    /**
     * 检查域名list的ip. 返回不匹配的域名
     *
     * @param domainList 域名list
     * @param defaultIp  后台的配置的系统ip
     * @return array
     */
    private JSONArray checkDomainIp(JSONArray domainList, String defaultIp) {
        return domainList.stream().filter(item -> {
            String domainIp = getDomainIp(String.valueOf(item));
            return !defaultIp.equals(domainIp);
        }).collect(Collectors.toCollection(JSONArray::new));
    }

    /**
     * 解析域名ip
     *
     * @param domain 域名或网址
     * @return String
     */
    private String getDomainIp(String domain) {
        try {
            InetAddress address = InetAddress.getByName(domain);
            return address.getHostAddress();
        } catch (Exception e) {
            SystemLog.ERROR().error("解析域名ip地址失败", e);
        }
        return null;
    }
}
